﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CPPEI.Coolzon.ServiceProxy
{
    public class ResponseKeeperV1
    {
        /// <summary>
        /// response的回复数量信息
        /// </summary>
        private List<RequestRegisterInfo> _requestList = new List<RequestRegisterInfo>();
        private object _lockObj = new object();

        /// <summary>
        /// 检查是否可用
        /// </summary>
        /// <param name="manager"></param>
        /// <param name="requestUniqueKey"></param>
        /// <param name="serviceAddress"></param>
        /// <param name="requestExpectantResponseCount"></param>
        /// <returns></returns>
        public bool IsUseable(ClientProxyManager manager, Guid requestUniqueKey, string[] serviceAddress, int requestExpectantResponseCount)
        {
            Retrive();

            RequestRegisterInfo existInfo = null;
            for (int index = 0; index < _requestList.Count; index++)
            {
                if (_requestList[index].UniqueKey == requestUniqueKey)
                {
                    existInfo = _requestList[index];
                    break;
                }
            }

            if (existInfo != null)
            {
                lock (existInfo)
                {
                    existInfo.ResponseCount++;
                }
                if (existInfo.ResponseCount == requestExpectantResponseCount)
                {
                    return true;
                }
                else
                {
                    // 判断本地可用的服务数量是否和实际的响应数量一致
                    if (existInfo.ResponseCount >= manager.GetAvailableMainServiceClientCount())
                    {
                        lock (existInfo)
                        {
                            existInfo.ResponseCount = existInfo.ExpectantResponseCount;
                        }
                        return true;
                    }
                    return false;
                }
            }
            else
            {
                // 不存在视为，来自其他客户端的指令
                if (requestExpectantResponseCount == 1)
                {
                    return true;
                }
                else
                {
                    // 判断本地可用的服务数量是否和实际的响应数量一致
                    if (requestExpectantResponseCount >= manager.GetAvailableMainServiceClientCount())
                    {
                        return true;
                    }

                    RequestRegisterInfo newInfo = Register(requestUniqueKey, serviceAddress, requestExpectantResponseCount);
                    lock (newInfo)
                    {
                        newInfo.ResponseCount++;
                    }
                    return false;
                }
            }
        }

        /// <summary>
        /// 注册请求的标志
        /// </summary>
        /// <param name="requestUniqueKey"></param>
        /// <param name="serviceAddress"></param>
        /// <param name="expectantResponseCount">预期的应答次数</param>
        internal RequestRegisterInfo Register(Guid requestUniqueKey, string[] serviceAddress, int expectantResponseCount)
        {
            RequestRegisterInfo info = new RequestRegisterInfo()
            {
                UniqueKey = requestUniqueKey,
                ExpectantResponseCount = expectantResponseCount,
                RegisterTicks = DateTime.Now.Ticks,
                ServiceAddress = serviceAddress
            };

            lock (_lockObj)
            {
                _requestList.Add(info);
            }
            return info;
        }

        /// <summary>
        /// 清楚过期的ResponseFlag
        /// </summary>
        public void Retrive()
        {
            lock (_lockObj)
            {
                long ticks = DateTime.Now.Ticks;
                for (int index = 0; index < _requestList.Count; )
                {
                    if (_requestList[index].ResponseCount == _requestList[index].ExpectantResponseCount)
                    {
                        _requestList.RemoveAt(index);
                        //Common.Logger.DebugToTag("ServiceProxy", "清理RequestRegisterInfo,达到预期的使用值");
                    }
                    else if (ticks - _requestList[index].RegisterTicks > TimeSpan.FromMinutes(1).Ticks)
                    {
                        // 时间超过1分钟的都清除
                        _requestList.RemoveAt(index);
                        Common.Logger.DebugToTag("ServiceProxy", "清理RequestRegisterInfo,清除原因超时1分钟");
                    }
                    else
                    {
                        index++;
                    }
                }
            }
        }
        
    }


    public class ResponseKeeperV2
    {
        /// <summary>
        /// 已处理过的请求列表
        /// </summary>
        private List<RequestRegisterInfo> _requestList = new List<RequestRegisterInfo>();
        private object _lockObj = new object();

        private object _checkObj = new object();

        /// <summary>
        /// 检查是否可用
        /// </summary>
        /// <param name="manager"></param>
        /// <param name="requestUniqueKey"></param>
        /// <param name="serviceAddress"></param>
        /// <param name="requestExpectantResponseCount"></param>
        /// <returns></returns>
        public bool IsUseable(ClientProxyManager manager, Guid requestUniqueKey, string[] serviceAddress, int requestExpectantResponseCount)
        {
            Retrive();

            lock (_checkObj)
            {
                RequestRegisterInfo existInfo = null;
                for (int index = 0; index < _requestList.Count; index++)
                {
                    if (_requestList[index].UniqueKey == requestUniqueKey)
                    {
                        existInfo = _requestList[index];
                        break;
                    }
                }

                if (existInfo != null)
                {
                    existInfo.ResponseCount++;
                    if (existInfo.ResponseCount == 1)
                    {
                        return true;
                    }
                    else
                    {
                        // 已经执行过，记录下收到新的回应
                        if (existInfo.ResponseCount >= manager.GetAvailableMainServiceClientCount())
                        {
                            existInfo.ResponseCount = existInfo.ExpectantResponseCount;
                        }
                        Common.Logger.WarningToTag("RemoteProxy", "不可用的请求requestUniqueKey：{0}，回应次数：{1}和可用的主服务客户端一样数量", requestUniqueKey, existInfo.ResponseCount);
                        return false;
                    }
                }
                else
                {
                    // 不存在视为，来自其他客户端的指令
                    if (requestExpectantResponseCount == 1)
                    {
                        // 只来自一个服务器
                        return true;
                    }
                    else
                    {
                        RequestRegisterInfo newInfo = Register(requestUniqueKey, serviceAddress, requestExpectantResponseCount);
                        lock (newInfo)
                        {
                            newInfo.ResponseCount++;
                        }
                        return true;
                    }
                }
            }
        }

        /// <summary>
        /// 注册请求的标志
        /// </summary>
        /// <param name="requestUniqueKey"></param>
        /// <param name="serviceAddress"></param>
        /// <param name="expectantResponseCount">预期的应答次数</param>
        internal RequestRegisterInfo Register(Guid requestUniqueKey, string[] serviceAddress, int expectantResponseCount)
        {
            RequestRegisterInfo info = new RequestRegisterInfo()
            {
                UniqueKey = requestUniqueKey,
                ExpectantResponseCount = expectantResponseCount,
                RegisterTicks = DateTime.Now.Ticks,
                ServiceAddress = serviceAddress
            };

            lock (_lockObj)
            {
                _requestList.Add(info);
            }
            return info;
        }

        /// <summary>
        /// 清楚过期的ResponseFlag
        /// </summary>
        public void Retrive()
        {
            lock (_lockObj)
            {
                long ticks = DateTime.Now.Ticks;
                for (int index = 0; index < _requestList.Count; )
                {
                    if (_requestList[index].ResponseCount == _requestList[index].ExpectantResponseCount)
                    {
                        _requestList.RemoveAt(index);
                        //Common.Logger.DebugToTag("ServiceProxy", "清理RequestRegisterInfo,达到预期的使用值");
                    }
                    else if (ticks - _requestList[index].RegisterTicks > TimeSpan.FromSeconds(30).Ticks)
                    {
                        // 时间超过1分钟的都清除
                        _requestList.RemoveAt(index);
                        Common.Logger.DebugToTag("ServiceProxy", "清理RequestRegisterInfo,清除原因超时30s");
                    }
                    else
                    {
                        index++;
                    }
                }
            }
        }

    }

    class RequestRegisterInfo
    {
        public Guid UniqueKey { get; set; }
        public int ExpectantResponseCount { get; set; }
        public int ResponseCount { get; set; }
        public long RegisterTicks { get; set; }
        public string[] ServiceAddress { get; set; }
    }
}
